"""
Clase que representa una imagen de tipo RGB, RGBA o GRAY,
contiene metodos para cargar una imagen desde un fichero, o asignar los
datos mediante una matriz, ademas permite acceder de forma matricial
a los datos almacenados

Autor: Gonzalo Luzardo Morocho
gluzardo@espol.edu.ec, gonchalox@gmail.com
"""

from PIL import Image
from numpy import *
from matplotlib.pyplot import imshow
import matplotlib.cm as cm

#Algunas defs
NONE = -1
GRAY = 1
RGB = 3
RGBA = 4

COLOR_MIN_VALUE = 0
COLOR_MAX_VALUE = 255

# IMAGEX CLASS
class Imagex:
	def __init__(self):
		self._colorMode = NONE
		self._height = 0
		self._width = 0
		self._channels = 0
		self._array = [] 
	
	# Carga los datos de la imagen desde un fichero
	def loadImage(self,filename):
        	image = Image.open(filename)
	        self._array = array(image)
	        
        	s = self._array.shape
        	self._height = s[0]
        	self._width = s[1]
        	if(len(s)>2):
        		self._channels = s[2]
        	else:
        		self._channels = 1	
        	
	        self._colorMode = self._channels
	
	
	# Retorna una imagen igual a la originalr
	def copy(self):
		img = Imagex()
		img._array = self._array.copy()
	        img._channels = self._channels
        	img._colorMode = self._colorMode
        	img._height = self._height
        	img._width = self._width
        	return img
        	
	#Setea la matriz de datos que va a contener la imagen
	def setData(self,data):
		self._array = data.copy()
		self._height = len(data)
		self._width = len(data[0])
		self._channels = size((self._array[0])[0])
		self._colorMode = self._channels
			
	#Muestra la imagen en un visor con interpolacion		  
	def imgShow(self):
		if self._colorMode == GRAY:
			return imshow(self._array, interpolation='nearest', vmin=COLOR_MIN_VALUE, vmax=COLOR_MAX_VALUE	, cmap=cm.gray)
		else:
			return imshow(self._array)
    
	# Obtiene un elemento de la matriz de datos
	# variable[x,y]
	def __getitem__(self, (x, y)):
        	return self._array[y % self._height, x % self._width]
    
	# Da valor a un elemento de la matriz de datos   
	# variable[x,y] = valor
	def __setitem__(self, (x, y), value):
        	self._array[y % self._height, x % self._width] = value
